package com.my.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.my.entity.User;
import com.my.mapper.UserMapper;
import com.my.service.UserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author: marshal
 * @date: 2023-05-25 14:34
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;


    /**
     * 测试不加@Transactional，看数据是否保存
     */
    @Override
    public void saveUser() {
        userMapper.insert(User.builder().name("Tom").age(11).build());
        // 运行时异常
        int i = 10 / 0;
        userMapper.insert(User.builder().name("Jack").age(13).build());
    }

    /**
     * 测试当发生异常时，数据是否回滚
     */
    @Override
//    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Transactional
    public void saveUser1() {
        userMapper.insert(User.builder().name("Tom1").age(11).build());
        // 运行时异常
        int i = 10 / 0;
        userMapper.insert(User.builder().name("Jack1").age(13).build());
    }

    /**
     * 测试调用本类的方法，事务是否生效
     */
    @Override
    public void saveUser2() {
        saveTomJack2();
    }

    @Transactional
    public void saveTomJack2() {
        userMapper.insert(User.builder().name("Tom2").age(11).build());
        // 运行时异常
        int i = 10 / 0;
        userMapper.insert(User.builder().name("Jack2").age(13).build());
    }

    /**
     * 测试调用本类的方法，事务是否生效
     */
    @Transactional
    @Override
    public void saveUser22() {
        saveTomJack22();
    }

    public void saveTomJack22() {
        userMapper.insert(User.builder().name("Tom22").age(11).build());
        // 运行时异常
        int i = 10 / 0;
        userMapper.insert(User.builder().name("Jack22").age(13).build());
    }


    /**
     * 测试使用try-catch处理异常后，事务是否生效
     */
    @Override
    @Transactional
    public void saveUser3() {
        userMapper.insert(User.builder().name("Tom3").age(11).build());
        // 运行时异常
        try {
            int i = 10 / 0;
        } catch (Exception e) {
            log.error("发生异常了，异常信息：{}", e.getMessage());
        }
        userMapper.insert(User.builder().name("Jack3").age(13).build());
    }

    /**
     * 测试使用@Transactional注解后，调用本类的不使用@Transactional的方法
     */
    @Transactional
    @Override
    public void saveUser4() {
        userMapper.insert(User.builder().name("Tom4").age(11).build());
        // 调用本类方法
        saveLucyAndJack4();
    }


    public void saveLucyAndJack4() {
        userMapper.insert(User.builder().name("Lucy4").age(13).build());
        int i = 10 / 0;
        userMapper.insert(User.builder().name("Jack4").age(13).build());
    }


    /**
     * 测试不使用@Transactional注解后，调用本类的使用@Transactional的方法
     */
    @Override
    public void saveUser5() {
        userMapper.insert(User.builder().name("Tom5").age(11).build());
        // 调用本类方法
        saveLucyAndJack5();
    }

    @Transactional
    public void saveLucyAndJack5() {
        userMapper.insert(User.builder().name("Lucy5").age(13).build());
        int i = 10 / 0;
        userMapper.insert(User.builder().name("Jack5").age(13).build());
    }

    /**
     * 测试，测试使用@Transactional注解后，调用本类的不使用@Transactional的方法。
     *  在SUPPORTS这个传播策略下，事务是否生效
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public void saveUser6() {
        userMapper.insert(User.builder().name("Tom6").age(11).build());
        // 调用本类方法
        saveLucyAndJack6();
    }


    public void saveLucyAndJack6() {
        userMapper.insert(User.builder().name("Lucy6").age(13).build());
        int i = 10 / 0;
        userMapper.insert(User.builder().name("Jack6").age(13).build());
    }

    /**
     *  测试发生IO异常时，事务是否生效
     *
     * @throws FileNotFoundException
     */
    @Transactional
    @Override
    public void saveUser7() throws FileNotFoundException {
        userMapper.insert(User.builder().name("Tom7").age(11).build());
        // 运行时异常
        FileInputStream file = new FileInputStream("aaaaa.txt");
        userMapper.insert(User.builder().name("Jack7").age(13).build());
    }

    /**
     * 测试项：当rollbackFor设置为FileNotFoundException.class或者IOException.class，然后发生IO异常时，事务是否生效
     *
     * @throws FileNotFoundException
     */
//    @Transactional(rollbackFor = FileNotFoundException.class)
    @Transactional(rollbackFor = IOException.class)
    @Override
    public void saveUser8() throws FileNotFoundException {
        userMapper.insert(User.builder().name("Tom8").age(11).build());
        // 运行时异常
        FileInputStream file = new FileInputStream("aaaaa.txt");
        userMapper.insert(User.builder().name("Jack8").age(13).build());
    }

    @Override
    @Transactional
    @Async
    public void saveUser9() {
        userMapper.insert(User.builder().name("Tom9").age(11).build());
        // 运行时异常
        int i = 10 / 0;
        userMapper.insert(User.builder().name("Jack9").age(13).build());
    }


}
